﻿using System;
using System.Collections;
using Com.Enemy.EnemySystem.Tools;
using Script.Com.Enemy.EnemySystem.EnemyAI;
using Script.Com.Enemy.EnemySystem.Tools;
using Script.EnemySystem.EnemyState;
using Script.EnemySystem.Tools;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Assertions.Must;

namespace Script.Com.Enemy.EnemySystem
{
    public class ArcherController : EnemyControllerBase
    {
        private ArcherStateState archerStateState;
        [SerializeField] private Animator arrowAnim;
        
        [SerializeField] private GameObject arrow;
        [SerializeField] private Transform shootPoint;
        [SerializeField] private float arrowSpeed = 30;

        private bool hadShot;
        private float aimTime;
        
        protected override void Awake()
        {
            base.Awake();
            archerStateState = gameObject.AddComponent<ArcherStateState>();
        }

        private void FixedUpdate()
        {
            if(isFollowPath)
                followPathAi.FollowPlayer();
        }

        protected override void MonsterAI()
        {
            if (body.Data.State == EnemyState.NormalAttack)
            {
                followPathAi.Flip(body.Target.position.x - transform.position.x);
                AinTipLine();
            }
            
            if (!body.Target || body.Data.State == EnemyState.Hurt || body.Data.State == EnemyState.Avoid)
            {
                return;
            }
            
            if (body.IsPlayerInArea)
            {
                float distance = Vector2.Distance(transform.position, body.Target.position);
                if (distance < body.Data.MeleeAttackDistance)
                {
                    if (!body.CoolDownSystem.HadColdDown(EnemyState.Avoid))
                    {
                        NormalAttack();
                    }
                    
                    DrawBack();
                    isFollowPath = false;
                }else if (distance < body.Data.RangedAttackDistance)
                {
                    //近身攻击
                    NormalAttack();
                    if(body.Data.State != EnemyState.Avoid)
                        rb.velocity = Vector2.zero;
                    isFollowPath = false;
                }
                else
                {
                    isFollowPath = true;
                    archerStateState.PlayState(EnemyState.Walk);
                }

            }
        }

        protected virtual void NormalAttack()
        {
            if (body.CoolDownSystem.HadColdDown(EnemyState.NormalAttack) && body.Data.State != EnemyState.NormalAttack)
            {
                aimTime = 0;
                hadShot = false;
                hit = Physics2D.Raycast(transform.position, body.Target.position - transform.position);
                archerStateState.PlayState(EnemyState.NormalAttack);
                
                arrowAnim.SetTrigger(Bow);
            }
        }
        
        protected virtual void DrawBack()
        {
            if (body.CoolDownSystem.HadColdDown(EnemyState.Avoid) && body.Data.State != EnemyState.Avoid)
            {
                archerStateState.PlayState(EnemyState.Avoid);

                StartCoroutine(AddBackForce());
            }
        }

        private IEnumerator PlayBowAnim()
        {
            yield return new WaitForSeconds(2f/6);
            arrowAnim.SetTrigger(Bow);
        }

        public void ShootArrow()
        {
            if (body.Data.State == EnemyState.NormalAttack)
            {
                if (!hit)
                {
                    return;
                }
                
                var position = shootPoint.position;
                GameObject go = Instantiate(arrow, position, Quaternion.identity);
                ArchersArrow archersArrow = go.GetComponent<ArchersArrow>();
                Vector2 dir = (Vector2)position - hit.point;
                float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;

                hadShot = true;
                archersArrow.SetTarget(hit.point, angle, arrowSpeed);
            }
        }

        private IEnumerator AddBackForce()
        {
            Vector3 back = (transform.position - body.Target.position).normalized;
            rb.velocity = back * 10;
            yield return new WaitForSeconds(.3f);  //后跳时间
            rb.velocity = Vector2.zero;
        }

        
        private RaycastHit2D hit;
        private bool waitForNextAim;
        private bool nextColorRed;
        private static readonly int Bow = Animator.StringToHash("bow");

        /// <summary>
        /// 瞄准 延迟一帧瞄准
        /// </summary>
        /// <returns></returns>
        private IEnumerator AimToShoot()
        {
            waitForNextAim = true;
            hit = Physics2D.Raycast(transform.position, body.Target.position - transform.position);

            Vector2 dir = (hit.point - (Vector2)arrowAnim.transform.position).normalized;


            float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
            
            

            if (transform.localScale.x > 0)
            {
                arrowAnim.transform.localScale = new Vector3(-1,1,1);
                arrowAnim.transform.localRotation = Quaternion.AngleAxis(angle, Vector3.forward);
            }
            else
            {
                arrowAnim.transform.localScale = new Vector3(1,1,1);
                arrowAnim.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
            }
            
            yield return new WaitForSeconds(Time.deltaTime);
            
            waitForNextAim = false;
        }

        private void AinTipLine()
        {
            
            if (aimTime / archerStateState.AnimTime.GetStateTime(EnemyState.NormalAttack) > .5f)
            {
                if (nextColorRed)
                {
                    nextColorRed = false;
                }
                else
                {
                    nextColorRed = true;
                }
            }
            
            aimTime += Time.deltaTime;
        }
        
        private void OnDrawGizmos()
        {
            if(!isActiveAndEnabled)
                return;
            
            if(body == null)
                return;

            if (body.Data.State != EnemyState.NormalAttack) return;

            if(hadShot)
                return;
            
            //射箭提示
            if (nextColorRed)
            {
                Gizmos.color = Color.white;
            }
            else
            {
                Gizmos.color = Color.red;
            }
            
            Gizmos.DrawLine(shootPoint.position, hit.point);
            
            if(!waitForNextAim)
                StartCoroutine(AimToShoot());


        }
        
    }
}
